<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<meta name="theme-color" content="#222"><meta name="generator" content="Hexo 6.3.0">

  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
  <link rel="mask-icon" href="/images/logo.svg" color="#222">

<link rel="stylesheet" href="/css/main.css">



<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css" integrity="sha256-CTSx/A06dm1B063156EVh15m6Y67pAjZZaQc89LLSrU=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.1.1/animate.min.css" integrity="sha256-PR7ttpcvz8qrF57fur/yAx1qXMFJeJFiA6pSzWi0OIE=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/fancyapps-ui/5.0.24/fancybox/fancybox.css" integrity="sha256-vQkngPS8jiHHH0I6ABTZroZk8NPZ7b+MUReOFE9UsXQ=" crossorigin="anonymous">

<script class="next-config" data-name="main" type="application/json">{"hostname":"rjyblog.gitee.io","root":"/","images":"/images","scheme":"Pisces","darkmode":false,"version":"8.18.2","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12},"copycode":{"enable":true,"style":null},"fold":{"enable":false,"height":500},"bookmark":{"enable":false,"color":"#222","save":"auto"},"mediumzoom":false,"lazyload":false,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"stickytabs":false,"motion":{"enable":true,"async":false,"transition":{"menu_item":"fadeInDown","post_block":"fadeIn","post_header":"fadeInDown","post_body":"fadeInDown","coll_header":"fadeInLeft","sidebar":"fadeInUp"}},"prism":false,"i18n":{"placeholder":"搜索...","empty":"没有找到任何搜索结果：${query}","hits_time":"找到 ${hits} 个搜索结果（用时 ${time} 毫秒）","hits":"找到 ${hits} 个搜索结果"},"path":"/search.xml","localsearch":{"enable":true,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false}}</script><script src="/js/config.js"></script>

    <meta name="description" content="SOLID和GRASP软件编程原则介绍">
<meta property="og:type" content="article">
<meta property="og:title" content="软件设计原则">
<meta property="og:url" content="https://rjyblog.gitee.io/posts/56256.html">
<meta property="og:site_name" content="任建勇的博客">
<meta property="og:description" content="SOLID和GRASP软件编程原则介绍">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://rjyblog.gitee.io/img/in-post/Traditional_Layers_Pattern.png">
<meta property="og:image" content="https://rjyblog.gitee.io/img/in-post/DIPLayersPattern.png">
<meta property="article:published_time" content="2019-09-03T16:00:00.000Z">
<meta property="article:modified_time" content="2023-08-17T01:46:48.285Z">
<meta property="article:author" content="Jason">
<meta property="article:tag" content="设计模式">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://rjyblog.gitee.io/img/in-post/Traditional_Layers_Pattern.png">


<link rel="canonical" href="https://rjyblog.gitee.io/posts/56256.html">



<script class="next-config" data-name="page" type="application/json">{"sidebar":"","isHome":false,"isPost":true,"lang":"zh-CN","comments":true,"permalink":"https://rjyblog.gitee.io/posts/56256.html","path":"posts/56256.html","title":"软件设计原则"}</script>

<script class="next-config" data-name="calendar" type="application/json">""</script>
<title>软件设计原则 | 任建勇的博客</title>
  








  <noscript>
    <link rel="stylesheet" href="/css/noscript.css">
  </noscript>
</head>

<body itemscope itemtype="http://schema.org/WebPage" class="use-motion">
  <div class="headband"></div>

  <main class="main">
    <div class="column">
      <header class="header" itemscope itemtype="http://schema.org/WPHeader"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏" role="button">
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
    </div>
  </div>

  <div class="site-meta">

    <a href="/" class="brand" rel="start">
      <i class="logo-line"></i>
      <p class="site-title">任建勇的博客</p>
      <i class="logo-line"></i>
    </a>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger" aria-label="搜索" role="button">
        <i class="fa fa-search fa-fw fa-lg"></i>
    </div>
  </div>
</div>



<nav class="site-nav">
  <ul class="main-menu menu"><li class="menu-item menu-item-home"><a href="/" rel="section"><i class="fa fa-home fa-fw"></i>首页</a></li><li class="menu-item menu-item-tags"><a href="/tags/" rel="section"><i class="fa fa-tags fa-fw"></i>标签</a></li><li class="menu-item menu-item-categories"><a href="/categories/" rel="section"><i class="fa fa-th fa-fw"></i>分类</a></li>
      <li class="menu-item menu-item-search">
        <a role="button" class="popup-trigger"><i class="fa fa-search fa-fw"></i>搜索
        </a>
      </li>
  </ul>
</nav>



  <div class="search-pop-overlay">
    <div class="popup search-popup"><div class="search-header">
  <span class="search-icon">
    <i class="fa fa-search"></i>
  </span>
  <div class="search-input-container">
    <input autocomplete="off" autocapitalize="off" maxlength="80"
           placeholder="搜索..." spellcheck="false"
           type="search" class="search-input">
  </div>
  <span class="popup-btn-close" role="button">
    <i class="fa fa-times-circle"></i>
  </span>
</div>
<div class="search-result-container no-result">
  <div class="search-result-icon">
    <i class="fa fa-spinner fa-pulse fa-5x"></i>
  </div>
</div>

    </div>
  </div>

</header>
        
  
  <aside class="sidebar">

    <div class="sidebar-inner sidebar-nav-active sidebar-toc-active">
      <ul class="sidebar-nav">
        <li class="sidebar-nav-toc">
          文章目录
        </li>
        <li class="sidebar-nav-overview">
          站点概览
        </li>
      </ul>

      <div class="sidebar-panel-container">
        <!--noindex-->
        <div class="post-toc-wrap sidebar-panel">
            <div class="post-toc animated"><ol class="nav"><li class="nav-item nav-level-3"><a class="nav-link" href="#SOLID"><span class="nav-text">SOLID</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#Single-responsibility-principle-%E5%8D%95%E4%B8%80%E8%81%8C%E8%B4%A3"><span class="nav-text">Single responsibility principle 单一职责</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#Open%E2%80%93closed-principle-%E5%BC%80%E9%97%AD%E5%8E%9F%E5%88%99"><span class="nav-text">Open–closed principle 开闭原则</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#Liskov-substitution-principle-%E9%87%8C%E5%BC%8F%E6%9B%BF%E6%8D%A2"><span class="nav-text">Liskov substitution principle 里式替换</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#Interface-segregation-principle-ISP"><span class="nav-text">Interface segregation principle (ISP)</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#Dependency-inversion-principle"><span class="nav-text">Dependency inversion principle</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#GRASP"><span class="nav-text">GRASP</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Separation-of-Concerns-%E5%85%B3%E6%B3%A8%E7%82%B9%E5%88%86%E7%A6%BB"><span class="nav-text">Separation of Concerns 关注点分离</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Don%E2%80%99t-Repeat-Yourself"><span class="nav-text">Don’t Repeat Yourself</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Inversion-of-Control"><span class="nav-text">Inversion of Control</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Dependency-Injection"><span class="nav-text">Dependency Injection</span></a></li></ol></div>
        </div>
        <!--/noindex-->

        <div class="site-overview-wrap sidebar-panel">
          <div class="site-author animated" itemprop="author" itemscope itemtype="http://schema.org/Person">
    <img class="site-author-image" itemprop="image" alt="Jason"
      src="/images/avatar.png">
  <p class="site-author-name" itemprop="name">Jason</p>
  <div class="site-description" itemprop="description"></div>
</div>
<div class="site-state-wrap animated">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
        <a href="/archives/">
          <span class="site-state-item-count">66</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
      <div class="site-state-item site-state-categories">
          <a href="/categories/">
        <span class="site-state-item-count">13</span>
        <span class="site-state-item-name">分类</span></a>
      </div>
      <div class="site-state-item site-state-tags">
          <a href="/tags/">
        <span class="site-state-item-count">23</span>
        <span class="site-state-item-name">标签</span></a>
      </div>
  </nav>
</div>

        </div>
      </div>
    </div>

    
  </aside>


    </div>

    <div class="main-inner post posts-expand">


  


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="https://rjyblog.gitee.io/posts/56256.html">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.png">
      <meta itemprop="name" content="Jason">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="任建勇的博客">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
      <meta itemprop="name" content="软件设计原则 | 任建勇的博客">
      <meta itemprop="description" content="SOLID和GRASP软件编程原则介绍">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          软件设计原则
        </h1>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2019-09-04 00:00:00" itemprop="dateCreated datePublished" datetime="2019-09-04T00:00:00+08:00">2019-09-04</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar-check"></i>
      </span>
      <span class="post-meta-item-text">更新于</span>
      <time title="修改时间：2023-08-17 09:46:48" itemprop="dateModified" datetime="2023-08-17T09:46:48+08:00">2023-08-17</time>
    </span>

  
</div>

            <div class="post-description">SOLID和GRASP软件编程原则介绍</div>
        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody"><h3 id="SOLID"><a href="#SOLID" class="headerlink" title="SOLID"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://en.wikipedia.org/wiki/SOLID">SOLID</a></h3><hr>
<h4 id="Single-responsibility-principle-单一职责"><a href="#Single-responsibility-principle-单一职责" class="headerlink" title="Single responsibility principle 单一职责"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://en.wikipedia.org/wiki/Single_responsibility_principle">Single responsibility principle</a> 单一职责</h4><p>The single responsibility principle is a computer programming principle that states that every module, class, or function should have responsibility over a single part of the functionality provided by the software, and that responsibility should be entirely encapsulated by the class, module or function. All its services should be narrowly aligned with that responsibility. Robert C. Martin expresses the principle as, “A class should have only one reason to change,” although, because of confusion around the word “reason” he more recently stated “This principle is about people.(Actor)”</p>
<p>Martin defines a responsibility as a reason to change, and concludes that a class or module should have one, and only one, reason to be changed (i.e. rewritten). As an example, consider a module that compiles and prints a report. Imagine such a module can be changed for two reasons. First, the content of the report could change. Second, the format of the report could change. These two things change for very different causes; one substantive, and one cosmetic. The single responsibility principle says that these two aspects of the problem are really two separate responsibilities, and should therefore be in separate classes or modules. It would be a bad design to couple two things that change for different reasons at different times.</p>
<p>The reason it is important to keep a class focused on a single concern is that it makes the class more robust. Continuing with the foregoing example, if there is a change to the report compilation process, there is greater danger that the printing code will break if it is part of the same class.</p>
<h4 id="Open–closed-principle-开闭原则"><a href="#Open–closed-principle-开闭原则" class="headerlink" title="Open–closed principle 开闭原则"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://en.wikipedia.org/wiki/Open%E2%80%93closed_principle">Open–closed principle</a> 开闭原则</h4><p>Open/closed principle states “software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification”; that is, such an entity can allow its behaviour to be extended without modifying its source code.</p>
<p>The name open/closed principle has been used in two ways. Both ways use generalizations (for instance, inheritance or delegate functions) to resolve the apparent dilemma, but the goals, techniques, and results are different.</p>
<h4 id="Liskov-substitution-principle-里式替换"><a href="#Liskov-substitution-principle-里式替换" class="headerlink" title="Liskov substitution principle 里式替换"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://en.wikipedia.org/wiki/Liskov_substitution_principle">Liskov substitution principle</a> 里式替换</h4><h4 id="Interface-segregation-principle-ISP"><a href="#Interface-segregation-principle-ISP" class="headerlink" title="Interface segregation principle (ISP)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://en.wikipedia.org/wiki/Interface_segregation_principle">Interface segregation principle (ISP)</a></h4><p>ISP states that no client should be forced to depend on methods it does not use. ISP splits interfaces that are very large into smaller and more specific ones so that clients will only have to know about the methods that are of interest to them. Such shrunken interfaces are also called role interfaces. ISP is intended to keep a system decoupled and thus easier to refactor, change, and redeploy.</p>
<h4 id="Dependency-inversion-principle"><a href="#Dependency-inversion-principle" class="headerlink" title="Dependency inversion principle"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://en.wikipedia.org/wiki/Dependency_inversion_principle">Dependency inversion principle</a></h4><p>In object-oriented design, the dependency inversion principle is a specific form of decoupling software modules. When following this principle, the conventional dependency relationships established from high-level, policy-setting modules to low-level, dependency modules are reversed, thus rendering high-level modules independent of the low-level module implementation details. The principle states:</p>
<ul>
<li>High-level modules should not depend on low-level modules. Both should depend on abstractions (e.g. interfaces).</li>
<li>Abstractions should not depend on details. Details (concrete implementations) should depend on abstractions.</li>
</ul>
<p>By dictating that both high-level and low-level objects must depend on the same abstraction, this design principle inverts the way some people may think about object-oriented programming.</p>
<p> Depend upon abstractions.  Do not depend upon concrete classes. P177</p>
<p> In conventional application architecture, lower-level components (e.g. Utility Layer) are designed to be consumed by higher-level components (e.g. Policy Layer) which enable increasingly complex systems to be built. In this composition, higher-level components depend directly upon lower-level components to achieve some task. This dependency upon lower-level components limits the reuse opportunities of the higher-level components.The goal of the dependency inversion pattern is to avoid this highly coupled distribution with the mediation of an abstract layer, and to increase the re-usability of higher/policy layers.<br> <img src="/img/in-post/Traditional_Layers_Pattern.png" alt="Traditional_Layers_Pattern" title="Traditional Layers Pattern"></p>
<p> With the addition of an abstract layer, both high- and lower-level layers reduce the traditional dependencies from top to bottom. Nevertheless, the “inversion” concept does not mean that lower-level layers depend on higher-level layers. Both layers should depend on abstractions that draw the behavior needed by higher-level layers.<br> <img src="/img/in-post/DIPLayersPattern.png" alt="DIPLayersPattern" title="DIP Layers Pattern"></p>
<p> In a direct application of dependency inversion, the abstracts are owned by the upper/policy layers. This architecture groups the higher/policy components and the abstractions that define lower services together in the same package. The lower-level layers are created by inheritance/implementation of these abstract classes or interfaces.[1]</p>
<p>The inversion of the dependencies and ownership encourages the re-usability of the higher/policy layers. Upper layers could use other implementations of the lower services. When the lower-level layer components are closed or when the application requires the reuse of existing services, it is common that an Adapter mediates between the services and the abstractions.</p>
<h3 id="GRASP"><a href="#GRASP" class="headerlink" title="GRASP"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://en.wikipedia.org/wiki/GRASP_(object-oriented_design)">GRASP</a></h3><hr>
<p>General Responsibility Assignment Software Patterns (or Principles), abbreviated GRASP, consist of guidelines for assigning responsibility to classes and objects in object-oriented design. It is not related to the <a target="_blank" rel="noopener external nofollow noreferrer" href="https://en.wikipedia.org/wiki/SOLID">SOLID</a> design principle.</p>
<p>The different patterns and principles used in GRASP are <a target="_blank" rel="noopener external nofollow noreferrer" href="https://en.wikipedia.org/wiki/GRASP_(object-oriented_design)#Controller">controller</a>, <a target="_blank" rel="noopener external nofollow noreferrer" href="https://en.wikipedia.org/wiki/GRASP_(object-oriented_design)#Creator">creator</a>, <a target="_blank" rel="noopener external nofollow noreferrer" href="https://en.wikipedia.org/wiki/GRASP_(object-oriented_design)#Indirection">indirection</a>, <a target="_blank" rel="noopener external nofollow noreferrer" href="https://en.wikipedia.org/wiki/GRASP_(object-oriented_design)#Information_expert">information expert</a>, <a target="_blank" rel="noopener external nofollow noreferrer" href="https://en.wikipedia.org/wiki/GRASP_(object-oriented_design)#High_cohesion">high cohesion</a>, <a target="_blank" rel="noopener external nofollow noreferrer" href="https://en.wikipedia.org/wiki/GRASP_(object-oriented_design)#Low_coupling">low coupling</a>, <a target="_blank" rel="noopener external nofollow noreferrer" href="https://en.wikipedia.org/wiki/GRASP_(object-oriented_design)#Polymorphism">polymorphism</a>, <a target="_blank" rel="noopener external nofollow noreferrer" href="https://en.wikipedia.org/wiki/GRASP_(object-oriented_design)#Protected_variations">protected variations</a>, and <a target="_blank" rel="noopener external nofollow noreferrer" href="https://en.wikipedia.org/wiki/GRASP_(object-oriented_design)#Pure_fabrication">pure fabrication</a>. All these patterns answer some software problems, and these problems are common to almost every software development project. These techniques have not been invented to create new ways of working, but to better document and standardize old, tried-and-tested programming principles in object-oriented design.</p>
<h3 id="Separation-of-Concerns-关注点分离"><a href="#Separation-of-Concerns-关注点分离" class="headerlink" title="Separation of Concerns 关注点分离"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://en.wikipedia.org/wiki/Separation_of_concerns">Separation of Concerns</a> 关注点分离</h3><hr>
<h3 id="Don’t-Repeat-Yourself"><a href="#Don’t-Repeat-Yourself" class="headerlink" title="Don’t Repeat Yourself"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://en.wikipedia.org/wiki/Don%27t_repeat_yourself">Don’t Repeat Yourself</a></h3><hr>
<h3 id="Inversion-of-Control"><a href="#Inversion-of-Control" class="headerlink" title="Inversion of Control"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://en.wikipedia.org/wiki/Inversion_of_control">Inversion of Control</a></h3><hr>
<p>Inversion of control is sometimes facetiously referred to as the “Hollywood Principle: Don’t call us, we’ll call you”.<br>(The Hollywood Principle: Don’t call us, we’ll call you. 《Head First design patterns - ora 2004》 P334)</p>
<p><a target="_blank" rel="noopener external nofollow noreferrer" href="https://martinfowler.com/bliki/InversionOfControl.html">Inversion of Control</a> by Martin Fowler</p>
<h3 id="Dependency-Injection"><a href="#Dependency-Injection" class="headerlink" title="Dependency Injection"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://en.wikipedia.org/wiki/Dependency_injection">Dependency Injection</a></h3><hr>

    </div>

    
    
    

    <footer class="post-footer">
          <div class="post-tags">
              <a href="/tags/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/" rel="tag"># 设计模式</a>
          </div>

        

          <div class="post-nav">
            <div class="post-nav-item">
                <a href="/posts/24313.html" rel="prev" title="APK 反编译">
                  <i class="fa fa-angle-left"></i> APK 反编译
                </a>
            </div>
            <div class="post-nav-item">
                <a href="/posts/31280.html" rel="next" title="Android Java虚拟机创建过程">
                  Android Java虚拟机创建过程 <i class="fa fa-angle-right"></i>
                </a>
            </div>
          </div>
    </footer>
  </article>
</div>






</div>
  </main>

  <footer class="footer">
    <div class="footer-inner">

  <div class="copyright">
    &copy; 
    <span itemprop="copyrightYear">2024</span>
    <span class="with-love">
      <i class="fa fa-heart"></i>
    </span>
    <span class="author" itemprop="copyrightHolder">Jason</span>
  </div>
  <div class="powered-by">由 <a href="https://hexo.io/" rel="noopener external nofollow noreferrer" target="_blank">Hexo</a> & <a href="https://theme-next.js.org/pisces/" rel="noopener external nofollow noreferrer" target="_blank">NexT.Pisces</a> 强力驱动
  </div>

    </div>
  </footer>

  
  <div class="back-to-top" role="button" aria-label="返回顶部">
    <i class="fa fa-arrow-up fa-lg"></i>
    <span>0%</span>
  </div>

<noscript>
  <div class="noscript-warning">Theme NexT works best with JavaScript enabled</div>
</noscript>


  
  <script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js" integrity="sha256-XL2inqUJaslATFnHdJOi9GfQ60on8Wx1C2H8DYiN1xY=" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/next-theme-pjax/0.6.0/pjax.min.js" integrity="sha256-vxLn1tSKWD4dqbMRyv940UYw4sXgMtYcK6reefzZrao=" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/fancyapps-ui/5.0.24/fancybox/fancybox.umd.js" integrity="sha256-oyhjPiYRWGXaAt+ny/mTMWOnN1GBoZDUQnzzgC7FRI4=" crossorigin="anonymous"></script>
<script src="/js/comments.js"></script><script src="/js/utils.js"></script><script src="/js/motion.js"></script><script src="/js/next-boot.js"></script><script src="/js/pjax.js"></script>

  <script src="https://cdnjs.cloudflare.com/ajax/libs/hexo-generator-searchdb/1.4.1/search.js" integrity="sha256-1kfA5uHPf65M5cphT2dvymhkuyHPQp5A53EGZOnOLmc=" crossorigin="anonymous"></script>
<script src="/js/third-party/search/local-search.js"></script>


  <script class="next-config" data-name="mermaid" type="application/json">{"enable":true,"theme":{"light":"default","dark":"dark"},"js":{"url":"https://cdnjs.cloudflare.com/ajax/libs/mermaid/10.5.0/mermaid.min.js","integrity":"sha256-K7oJiQlDulzl24ZUFOywuYme1JqBBvQzK6m8qHjt9Gk="}}</script>
  <script type="module" src="/js/zenuml-definition-074a43fa.js"></script>
  <script type="module" src="/js/mermaid-zenuml.esm.min.mjs"></script>
  <script src="/js/third-party/tags/mermaid.js"></script>


  <script src="/js/third-party/fancybox.js"></script>



  




  

  <script class="next-config" data-name="enableMath" type="application/json">true</script><script class="next-config" data-name="mathjax" type="application/json">{"enable":true,"tags":"none","js":{"url":"https://cdnjs.cloudflare.com/ajax/libs/mathjax/3.2.2/es5/tex-mml-chtml.js","integrity":"sha256-MASABpB4tYktI2Oitl4t+78w/lyA+D7b/s9GEP0JOGI="}}</script>
<script src="/js/third-party/math/mathjax.js"></script>



</body>
</html>
